<?php

declare(strict_types=1);

namespace Service\WebSocketService;

use Service\BaseService;
use Service\Code\Normal;
use Service\ExportService\ExportExcelHandle;
use App\Model\BbcModel\Goods;
use App\Model\BbcModel\GoodsSpecPrice;
use App\Model\BbcModel\DistributorLevel;
use App\Model\BbcModel\DistributorPrice;
use App\Model\BbcModel\ManagerChannel;
use App\Model\BbcModel\MnStoreGoods;
use App\Model\BbcModel\GoodsImportLog;
use App\Model\BbcModel\CashGoodsChange;
use App\Model\BbcModel\GoodsLog;
use Hyperf\DbConnection\Db;

/**
 * 渠道商品-商品资料导入修改
 * @author huj
 */
class ChannelCommodityPriceEditService extends BaseService {
    const CHUNK_NUM = 50;

    /**
     * 商品价格导入修改
     * @param object $server
     * @param int $fd
     * @param array $body
     * @param int $manager_id
     * @param int $cid
     * 推送前端客户端方式
     * Normal::returnCode(Normal::WS_START,"开始处理");
     * Normal::returnCode(Normal::WS_END,"处理完成");
     * Normal::returnCode(Normal::WS_ERROR,"处理异常");
     * $server->push($fd,json_encode($result,JSON_UNESCAPED_UNICODE));
     */
    public function batchUpdate($server, int $fd, array $body, int $manager_id, int $cid) {
        // $body = [
        //     'isUploadFile' => 1,
        //     'fileUrl'      => "https://indoorbuydev.oss-cn-hangzhou.aliyuncs.com/sbbc/channel/upload/修改商品资料模板_2023081016135035861.xlsx",
        //     'upLoadData'   => [
        //         ['2205111130377232', '1,2', '10.30,18.54', "11.02,19.83", '11.42,20.56', '5.30,27.54', '10.20,18.36', '奶昔杯-10', '4578480', '10.30,18.54'],
        //         ['2205111130375785', '1,2', '1.96,3.82', "2.10,4.08", '2.17,4.23', '2.91,5.67', '1.94,3.78', '奶昔杯-9', '4578479', '1.96,3.82'],
        //     ],
        // ];
        if (!isset($body['isUploadFile']) || empty($body['isUploadFile'])) {
            return Normal::returnCode(Normal::WS_ERROR, '需上传文件');
        }
        if (!isset($body['fileUrl']) || empty($body['fileUrl'])) {
            return Normal::returnCode(Normal::WS_ERROR, '上传到oss的文件链接为空');
        }
        if (!isset($body['upLoadData']) || empty($body['upLoadData'])) {
            return Normal::returnCode(Normal::WS_ERROR, '上传的文件数据为空');
        }
        $originFileUrl  = $body['fileUrl'];
        $pathInfo       = pathinfo($originFileUrl);
        $originFileName = $pathInfo['filename'] ?? $pathInfo['basename'];
        $list           = $body['upLoadData'];
        $managerInfo    = $this->managerInfo($manager_id);
        //去除空行数据
        foreach ($list as $key => $item) {
            $checkCol = array_filter($item);
            if (empty($checkCol) || empty(reset($item))) {
                unset($list[$key]);
            }
        }
        $skuList                 = array_filter(array_column($list, 0));
        $distributor_level       = DistributorLevel::where('cid', $cid)->orderBy('level', 'asc')->orderBy('id', 'asc')->select(['level', 'name'])->get()->toArray();
        $distributor_level_index = $distributor_level ? array_column($distributor_level, 'name', 'level') : [];
        $fields                  = [
            'id', 'medicinal', 'price_recommend', 'is_trade', 'price_recommend_vip', 'price_store', 'base_spec', 'tax_free',
            'tax_rate', 'high_tax_rate', 'is_bonded', 'high_price', 'price_cost', 'skucode'
        ];
        $allGoods                = Goods::whereIn('skucode', $skuList)->where('cid', $cid)->select($fields)->get()->toArray();
        $allGoodsBySku           = array_column($allGoods, null, 'skucode');
        $goods_ids               = array_column($allGoods, 'id');
        $goodsSpec               = GoodsSpecPrice::whereIn('goods_id', $goods_ids)->orderBy('spec_num', 'asc')->get()->toArray();
        $specBygid               = [];
        if ($goodsSpec) {
            foreach ($goodsSpec as $spec) {
                $specBygid[$spec['goods_id']][] = $spec;
            }
        }
        $storeListFileds = ['mg.id', 'mg.type', 'mg.profit', 'mg.profit_vip', 'u.price_limit', 'mg.price', 'mg.price_vip', 'u.level', 'mg.goods_id'];
        $storeListAll    = MnStoreGoods::query()->from((new MnStoreGoods)->getTable() . ' as mg')->leftJoin('ly_mn_user as u', 'mg.mn_sid', '=', 'u.id')
            ->whereIn('mg.goods_id', $goods_ids)->select($storeListFileds)->get();

        if ($server) {
            $send = Normal::returnCode(Normal::WS_START, "进行中", [
                'percent' => 5,
            ]);
            $server->push($fd, json_encode($send, JSON_UNESCAPED_UNICODE));
        }
        $errorData           = [];
        $saveData            = [];//更新
        $specPriceData       = [];//更新
        $storeGoodsData      = [];//更新
        $cashGoodsChangeData = [];//新增
        $dstbPriceDel        = [];//删除
        $dstbPriceData       = [];//新增
        $goodsLogData        = [];//新增
        $timeStp             = time();
        foreach ($list as $v) {
            $skuCode = $v[0];
            if (!isset($allGoodsBySku[$skuCode])) {
                array_push($v, '自编码对应商品不存在');
                $errorData[] = $v;
                continue;
            }
            $res1 = $this->regex($v[1], '/^[1-9]+(,[1-9]+)*$/');
            if (!$res1) {
                array_push($v, '规格数量设置错误 多个规格间英文逗号隔开');
                $errorData[] = $v;
                continue;
            }
            $res2 = $this->regex($v[2], '/^(\d+(\.\d{0,2}+)?)(,\d+(\.\d{0,2}+)?)*$/');
            if (!$res2) {
                array_push($v, '下游结算价设置错误 价格保留小数点后两位 多个价格用英文逗号隔开');
                $errorData[] = $v;
                continue;
            }
            $res3 = $this->regex($v[3], '/^(\d+(\.\d{0,2}+)?)(,\d+(\.\d{0,2}+)?)*$/');
            if (!$res3) {
                array_push($v, '推荐会员价设置错误 价格保留小数点后两位 多个价格用英文逗号隔开');
                $errorData[] = $v;
                continue;
            }
            $res4 = $this->regex($v[4], '/^(\d+(\.\d{0,2}+)?)(,\d+(\.\d{0,2}+)?)*$/');
            if (!$res4) {
                array_push($v, '推荐零售价设置错误 价格保留小数点后两位 多个价格用英文逗号隔开');
                $errorData[] = $v;
                continue;
            }
            if (empty($v[5]) || is_null($v[5])) {
                // $v[5] = false;
                $v[5] = '';
            } else {
                $res5 = $this->regex($v[5], '/^(\d+(\.\d{0,2}+)?)(,\d+(\.\d{0,2}+)?)*$/');
                if (!$res5) {
                    array_push($v, '市场价设置错误 价格保留小数点后两位 多个价格用英文逗号隔开');
                    $errorData[] = $v;
                    continue;
                }
            }
            $res6 = $this->regex($v[6], '/^(\d+(\.\d{0,2}+)?)(,\d+(\.\d{0,2}+)?)*$/');
            if (!$res6) {
                array_push($v, '成本价设置错误 价格保留小数点后两位 多个价格用英文逗号隔开');
                $errorData[] = $v;
                continue;
            }
            $row                 = $allGoodsBySku[$skuCode];
            $specListOld         = $specBygid[$row['id']] ?? [];
            $specListOld         = collect($specListOld)->sortBy('spec_num')->toArray();
            $specListOld         = array_column($specListOld, null, 'spec_num');
            $specList            = explode(',', $v[1]);
            $price_store         = explode(',', $v[2]);
            $price_recommend_vip = explode(',', $v[3]);
            $price_recommend     = explode(',', $v[4]);
            $price_market        = explode(',', $v[5]);
            $price_cost          = explode(',', $v[6]);
            $priceCount          = count($specList);
            if (count($price_store) == 1 || count($price_recommend_vip) == 1 || count($price_recommend) == 1) {
                $priceCount = 1;
            }
            if ($priceCount == 1) {
                if ($price_store[0] < $price_cost[0] && $row['medicinal'] == 0) {
                    array_push($v, '成本价不能大于结算价');
                    $errorData[] = $v;
                    continue;
                }
                if ($price_store[0] > $price_recommend_vip[0]) {
                    array_push($v, '结算价不能大于推荐价格');
                    $errorData[] = $v;
                    continue;
                }
                if ($price_recommend[0] < $price_recommend_vip[0]) {
                    array_push($v, '推荐零售价不能小于推荐会员价');
                    $errorData[] = $v;
                    continue;
                }
                if (isset($price_market[0]) && $price_market[0] < $price_recommend_vip[0]) {
                    array_push($v, '市场价不能低于推荐会员价');
                    $errorData[] = $v;
                    continue;
                }
                if (isset($price_market[0]) && $price_market[0] < $price_recommend[0]) {
                    array_push($v, '市场价不能低于推荐零售价');
                    $errorData[] = $v;
                    continue;
                }
                if ($row['is_trade'] == 0) {
                    foreach ($specListOld as $key => $value) {
                        if (isset($price_market[0])) {
                            $specListOld[$key]['price_market'] = $price_market[0] / $specList[0] * $value['spec_num'];
                        }
                        $specListOld[$key]['price_store'] = $price_store[0] / $specList[0] * $value['spec_num'];
                        if ($row['medicinal'] <> 2) {
                            $specListOld[$key]['price_recommend']     = $price_recommend[0] / $specList[0] * $value['spec_num'];
                            $specListOld[$key]['price_recommend_vip'] = $price_recommend_vip[0] / $specList[0] * $value['spec_num'];
                        }
                    }
                } else {
                    if ($row['medicinal'] == 1) {
                        if ($price_recommend_vip[0] < $row['price_recommend'] || $price_store[0] < $row['price_recommend_vip']) {
                            array_push($v, '限价商品零售价不能低于推荐价格');
                            $errorData[] = $v;
                            continue;
                        }
                    }
                }
                //等级分销商结算价判断
                $i               = 1;
                $distributorFlag = true;
                $distributorMsg  = '';
                foreach ($distributor_level_index as $key => $val) {
                    if (!is_array($v[8 + $i])) {
                        $v[8 + $i] = explode(',', $v[8 + $i]);
                    }
                    if ($v[8 + $i][0] < $price_cost[0] && $row['medicinal'] == 0) {
                        $distributorMsg  = $val . '的分销价格不能低于成本价';
                        $distributorFlag = false;
                        break;
                    }
                    if ($v[8 + $i][0] > $price_recommend_vip[0]) {
                        $distributorMsg  = $val . '的分销价格不能大于推荐会员价';
                        $distributorFlag = false;
                        break;
                    }
                    if ($v[8 + $i][0] > $price_recommend[0]) {
                        $distributorMsg  = $val . '的分销价格不能大于推荐零售价';
                        $distributorFlag = false;
                        break;
                    }
                    $i++;
                }
                if ($distributorFlag === false && !empty($distributorMsg)) {
                    array_push($v, $distributorMsg);
                    $errorData[] = $v;
                    continue;
                }
            } else {
                if ($row['is_trade'] == 0) {
                    if (count($specList) <> count($specListOld)) {
                        array_push($v, '规格数量不能修改');
                        $errorData[] = $v;
                        continue;
                    }
                }
                if (count($specList) <> count($price_store)) {
                    array_push($v, '规格数量与下游结算价数量不相等');
                    $errorData[] = $v;
                    continue;
                }
                if (count($specList) <> count($price_market)) {
                    array_push($v, '规格数量与市场价数量不相等');
                    $errorData[] = $v;
                    continue;
                }
                if (count($specList) <> count($price_recommend_vip)) {
                    array_push($v, '规格数量与推荐会员价数量不相等');
                    $errorData[] = $v;
                    continue;
                }
                if (count($specList) <> count($price_recommend)) {
                    array_push($v, '规格数量与推荐零售价数量不相等');
                    $errorData[] = $v;
                    continue;
                }
                // if(count($specList) <> count($price_market)){
                //     $v[]='规格数量与市场价数量不相等';
                //     $out[]=$v;
                //     continue;
                // }
                if (count($specList) <> count($price_cost)) {
                    array_push($v, '规格数量与成本价数量不相等');
                    $errorData[] = $v;
                    continue;
                }
                $msg1  = '';
                $flag1 = true;
                foreach ($specList as $spec => $spec_num) {
                    if (!empty($row) && $price_store[$spec] < $price_cost[$spec] && $row['medicinal'] == 0) {
                        $msg1  = "规格{$spec_num}的" . '成本价不能大于结算价';
                        $flag1 = false;
                        break;
                    }
                    if (!empty($row) && $price_store[$spec] > $price_recommend_vip[$spec]) {
                        $msg1  = "规格{$spec_num}的" . '结算价不能大于推荐价格';
                        $flag1 = false;
                        break;
                    }
                    if (!empty($row) && $price_recommend[$spec] < $price_recommend_vip[$spec]) {
                        $msg1  = "规格{$spec_num}的" . '推荐零售价不能小于推荐会员价';
                        $flag1 = false;
                        break;
                    }
                    if (!empty($row) && isset($price_market[$spec]) && $price_recommend[$spec] > $price_market[$spec]) {
                        $msg1  = "规格{$spec_num}的" . '推荐零售价不能大于市场价';
                        $flag1 = false;
                        break;
                    }
                    if (!empty($row) && isset($price_market[$spec]) && $price_recommend_vip[$spec] > $price_market[$spec]) {
                        $msg1  = "规格{$spec_num}的" . '推荐会员价不能大于市场价';
                        $flag1 = false;
                        break;
                    }
                    if ($row['is_trade'] == 0) {
                        if (!empty($row) && $row['medicinal'] == 1) {
                            if ($price_recommend_vip[$spec] < $specListOld[$spec_num]['price_recommend'] || $price_store[$spec] < $specListOld[$spec_num]['price_recommend_vip']) {
                                $msg1  = "规格{$spec_num}的" . '限价商品零售价不能低于推荐价格';
                                $flag1 = false;
                                break;
                            }
                        }
                        if (isset($price_market[$spec])) {
                            $specListOld[$spec_num]['price_market'] = $price_market[$spec];
                        }
                        $specListOld[$spec_num]['price_store'] = $price_store[$spec];
                        if ($row['medicinal'] <> 2) {
                            $specListOld[$spec_num]['price_recommend']     = $price_recommend[$spec];
                            $specListOld[$spec_num]['price_recommend_vip'] = $price_recommend_vip[$spec];
                        }
                    } else {
                        if (!empty($row) && $row['medicinal'] == 1) {
                            if ($price_recommend_vip[$spec] < $row['price_recommend'] || $price_store[$spec] < $row['price_recommend_vip']) {
                                $msg1  = "规格{$spec_num}的" . '限价商品零售价不能低于推荐价格';
                                $flag1 = false;
                                break;
                            }
                        }
                    }
                    //等级分销商结算价判断
                    $msg2  = '';
                    $flag2 = true;
                    $i     = 1;
                    foreach ($distributor_level_index as $key => $val) {
                        if (!is_array($v[8 + $i])) {
                            $v[8 + $i] = explode(',', $v[8 + $i]);
                        }
                        if (!empty($v[8 + $i][$spec])) { //设置了分销商价格
                            if ($v[8 + $i][$spec] < $price_cost[$spec] && $row['medicinal'] == 0) {
                                $msg2  = $val . '的分销价格不能低于成本价';
                                $flag2 = false;
                                break;
                            }
                            if ($v[8 + $i][$spec] > $price_recommend_vip[$spec]) {
                                $msg2  = $val . '的分销价格不能大于推荐会员价';
                                $flag2 = false;
                                break;
                            }
                            if ($v[8 + $i][$spec] > $price_recommend[$spec]) {
                                $msg2  = $val . '的分销价格不能大于推荐零售价';
                                $flag2 = false;
                                break;
                            }
                        } else {
                            $v[8 + $i][$spec] = $price_store[$spec];
                        }
                        $i++;
                    }
                    if ($flag2 === false && !empty($msg2)) {
                        $msg1  = $msg2;
                        $flag1 = false;
                        break;
                    }
                }
                if ($flag1 === false && !empty($msg1)) {
                    array_push($v, $msg1);
                    $errorData[] = $v;
                    continue;
                }
            }
            if ($row['is_bonded'] == 1 && $row['tax_free'] == 1) {
                if ($row['high_price'] > 0) {
                    $pricestoretax_rate = $row['tax_rate'];
                    $pricecosttax_rate  = $row['tax_rate'];
                    if ($price_store[0] >= $row['high_price']) {
                        $pricestoretax_rate = $row['high_tax_rate'];
                    }
                    if ($row['price_cost'] >= $row['high_price']) {
                        $pricecosttax_rate = $row['high_tax_rate'];
                    }
                    $except_money = round(($price_store[0] / (1 + $pricestoretax_rate) - $row['price_cost'] / (1 + $pricecosttax_rate)), 2);
                } else {
                    $except_money = round(($price_store[0] / (1 + $row['tax_rate']) - $row['price_cost'] / (1 + $row['tax_rate'])), 2);
                }
                if ($except_money < 0) {
                    array_push($v, '修改价格失败，渠道利润为负');
                    $errorData[] = $v;
                    continue;
                }
            }
            $rowData = [
                'id'          => $row['id'],
                'price_store' => $price_store[0],
                'md'          => $timeStp,
                'type'        => 2,
                'is_update'   => 0,
            ];
            if (isset($price_market[0])) {
                $rowData['price_market'] = $price_market[0];
            } else {
                $rowData['price_market'] = $row['price_market'];
            }
            if ($row['medicinal'] <> 2) {
                $rowData['price_recommend']     = $price_recommend[0];
                $rowData['price_recommend_vip'] = $price_recommend_vip[0];
            } else {
                $rowData['price_recommend']     = $row['price_recommend'];
                $rowData['price_recommend_vip'] = $row['price_recommend_vip'];
            }
            if ($row['is_trade'] == 1) {
                $rowData['price_cost'] = $price_cost[0];
            } else {
                $rowData['price_cost'] = $row['price_cost'];
            }
            $rowData['is_high_goods'] = 0;
            if ($row['is_bonded'] == 1 && $row['high_price'] > 0 && ($rowData['price_store'] >= $row['high_price'] || $rowData['price_recommend'] >= $row['high_price'] || $rowData['price_recommend_vip'] >= $row['high_price'])) {
                $rowData['is_high_goods'] = 1;
            }
            if (!empty($specListOld)) {
                foreach ($specListOld as $vv) {
                    $specPriceData[] = $vv;
                }
            }
            //分销商等级结算价
            $distributor_level_price = [];
            if ($distributor_level_index) { //设置了分销商等级
                if ($priceCount == 1) {
                    $i = 1;
                    foreach ($distributor_level_index as $key => $val) {
                        foreach ($specListOld as $spec => $spec_num) {
                            $unitData                  = ['sid' => getSID(), 'cid' => $cid, 'goods_id' => $row['id'], 'price' => $v[8 + $i][0] * $spec_num['spec_num'], 'spec_num' => $spec_num['spec_num'], 'level_id' => $key, 'cd' => $timeStp];
                            $distributor_level_price[] = $unitData;
                            $dstbPriceData[]           = $unitData;
                        }
                        $v[8 + $i] = implode(',', $v[8 + $i]);
                        $i++;
                    }
                } else {
                    $l = 1;
                    foreach ($distributor_level_index as $key => $val) {
                        foreach ($specList as $spec => $spec_num) {
                            $unitData                  = ['sid' => getSID(), 'cid' => $cid, 'goods_id' => $row['id'], 'price' => $v[8 + $l][$spec], 'spec_num' => $spec_num, 'level_id' => $key, 'cd' => $timeStp];
                            $distributor_level_price[] = $unitData;
                            $dstbPriceData[]           = $unitData;
                        }
                        $v[8 + $l] = implode(',', $v[8 + $l]);
                        $l++;
                    }
                }
                array_push($dstbPriceDel, $row['id']);
                // Db::table('ly_distributor_price')->where(['sid'=>config('STORE_ID'),'cid'=>$this->cid,'goods_id'=>$code['id']])->delete();
            }
            $level_price = [];
            if (!empty($distributor_level_price)) {
                $level_price = array_column($distributor_level_price, null, 'level_id');
            }
            if ($rowData['price_store'] != $row['price_store']) {
                $storeList = [];
                if ($storeListAll->isNotEmpty()) {
                    $storeList = $storeListAll->where('goods_id', $row['id'])->toArray();
                }
                $e_price     = $rowData['price_recommend'] ?? $row['price_recommend'];
                $e_price_vip = $rowData['price_recommend_vip'] ?? $row['price_recommend_vip'];
                if (!empty($storeList)) {
                    foreach ($storeList as $gk => $gv) {
                        $storePriceStore = $rowData['price_store'];
                        if (isset($level_price[$gv['level']]['price'])) {
                            $storePriceStore = $level_price[$gv['level']]['price'];
                        }
                        switch ($gv['type']) {
                            case 0:
                                $storeList[$gk]['price']     = $storePriceStore + $gv['profit'];
                                $storeList[$gk]['price_vip'] = $storePriceStore + $gv['profit_vip'];
                                break;
                            case 1:
                                $storeList[$gk]['price']     = $storePriceStore + $storePriceStore * $gv['profit'] / 100;
                                $storeList[$gk]['price_vip'] = $storePriceStore + $storePriceStore * $gv['profit_vip'] / 100;
                                break;
                            case 2:
                            default:
                                $storeList[$gk]['price']     = $e_price;
                                $storeList[$gk]['price_vip'] = $e_price_vip;
                                break;
                            case 3:
                                $storeList[$gk]['price']     = $gv['price'];
                                $storeList[$gk]['price_vip'] = $gv['price_vip'];
                                break;
                        }
                        if ($gv['price_limit'] == 1 && $storeList[$gk]['price_vip'] > $e_price_vip) {
                            $storeList[$gk]['price']     = $e_price;
                            $storeList[$gk]['price_vip'] = $e_price_vip;
                            $storeList[$gk]['type']      = 2;
                        }
                        if ($row['is_bonded'] == 1 && $row['tax_free'] == 0) {
                            $storeList[$gk]['price']     = ($storeList[$gk]['price'] * (1 + $row['tax_rate'])) / $row['base_spec'];
                            $storeList[$gk]['price_vip'] = ($storeList[$gk]['price_vip'] * (1 + $row['tax_rate'])) / $row['base_spec'];
                        } else {
                            $storeList[$gk]['price']     = $storeList[$gk]['price'] / $row['base_spec'];
                            $storeList[$gk]['price_vip'] = $storeList[$gk]['price_vip'] / $row['base_spec'];
                        }
                        $storeList[$gk]['md']            = $timeStp;
                        $storeList[$gk]['is_high_goods'] = 0;
                        if ($row['is_bonded'] == 1 && $row['high_price'] > 0 && ($storeList[$gk]['price'] >= $row['high_price'] || $storeList[$gk]['price_vip'] >= $row['high_price'])) {
                            $storeList[$gk]['is_high_goods'] = 1;
                        }
                    }
                    $storeGoodsData = array_merge($storeGoodsData, $storeList);
                }
            } elseif ((!empty($rowData['price_recommend']) && $rowData['price_recommend'] <> $row['price_store']) || (!empty($rowData['price_recommend_vip']) && $rowData['price_recommend_vip'] <> $row['price_recommend_vip'])) {
                $storeList = [];
                if ($storeListAll->isNotEmpty()) {
                    $storeList = $storeListAll->where('goods_id', $row['id'])->where('type', 2)->take(5)->toArray();
                }
                $e_price     = $rowData['price_recommend'] ?? $row['price_recommend'];
                $e_price_vip = $rowData['price_recommend_vip'] ?? $row['price_recommend_vip'];
                if (!empty($storeList)) {
                    foreach ($storeList as $gk => $gv) {
                        if ($row['is_bonded'] == 1 && $row['tax_free'] == 0) {
                            $storeList[$gk]['price']     = ($e_price * (1 + $row['tax_rate'])) / $row['base_spec'];
                            $storeList[$gk]['price_vip'] = ($e_price_vip * (1 + $row['tax_rate'])) / $row['base_spec'];
                        } else {
                            $storeList[$gk]['price']     = $e_price / $row['base_spec'];
                            $storeList[$gk]['price_vip'] = $e_price_vip / $row['base_spec'];
                        }
                        $storeList[$gk]['md']            = $timeStp;
                        $storeList[$gk]['is_high_goods'] = 0;
                        if ($row['is_bonded'] == 1 && $row['high_price'] > 0 && ($storeList[$gk]['price'] >= $row['high_price'] || $storeList[$gk]['price_vip'] >= $row['high_price'])) {
                            $storeList[$gk]['is_high_goods'] = 1;
                        }
                    }
                    $storeGoodsData = array_merge($storeGoodsData, $storeList);
                    // MnStoreGoods::instance()->saveAll($storeList);
                }
            }
            $cashGoodsChangeData[] = [
                'cid'      => $cid,
                'mn_sid'   => 0,
                'goods_id' => $row['id'],
                'cd'       => $timeStp
            ];
            $goodsLogData[]        = [
                'manager_id'   => $manager_id,
                'manager_name' => $managerInfo['name'],
                'common_id'    => $row['id'],
                'old'          => json_encode($row, 320),
                'info'         => json_encode($rowData, 320),
                'ip'           => $server->getClientInfo($fd)['remote_ip'],
                'cd'           => $timeStp,
                'sid'          => getSID()
            ];

            $saveData[] = $rowData;
        }
        if (!empty($errorData)) {
            $fileName  = "商品价格导入修改错误信息.xlsx";
            $headArr   = $this->getColumns($distributor_level_index);
            $exportRes = ExportExcelHandle::instance()->uploadAliOssSource($fileName, $headArr, $errorData);
            if ($exportRes['code'] != Normal::SUC) {
                return Normal::returnCode(Normal::WS_ERROR, $exportRes['msg'] ?? '生成商品价格导入修改错误信息失败');
            }
            $download_url = $exportRes['data']['path'];
        }
        if ($server) {
            $send = Normal::returnCode(Normal::WS_START, "进行中", [
                'percent' => 10,
            ]);
            $server->push($fd, json_encode($send, JSON_UNESCAPED_UNICODE));
        }
        $count = count($saveData);
        if ($count == 0) {
            //保存到导入日志
            $importLog = [
                'cid'             => $cid,
                'file_name'       => $originFileName,
                'import_type'     => 2,
                'all_num'         => count($list),
                'success_num'     => $count,
                'fail_num'        => count($errorData),
                'status'          => count($errorData) > 0 ? 2 : 1,
                'origin_file_url' => $originFileUrl,
                'fail_file_url'   => $download_url ?? '',
                'manager_id'      => $manager_id,
                'manager_name'    => $managerInfo['name'],
                'cd'              => $timeStp,
                'md'              => $timeStp,
            ];
            GoodsImportLog::insert($importLog);
            if ($server) {
                $send = Normal::returnCode(Normal::WS_END, "已完成", [
                    'percent'      => 100,
                    'download_url' => $download_url ?? '',
                ]);
                $server->push($fd, json_encode($send, JSON_UNESCAPED_UNICODE));
            }
        }
        $newSaveData = array_column($saveData, null, 'id');
        $chunkData   = array_chunk($newSaveData, self::CHUNK_NUM);
        $percent     = 10.00;
        Db::beginTransaction();
        try {
            foreach ($chunkData as $k => $upData) {
                //执行批量更新  商品表
                $fields1        = ['price_store', 'md', 'type', 'is_update', 'price_market', 'price_recommend', 'price_recommend_vip', 'price_cost', 'is_high_goods'];
                $sqlArr1        = $this->mergeSql($upData, $fields1);
                $updateSqlStr1  = implode(",", $sqlArr1['updateSql']);
                $whereIds1      = implode(",", $sqlArr1['ids']);
                $databaseName1  = Goods::instance()->getConnection()->getDatabaseName();
                $tableName1     = Goods::instance()->getTable();
                $sql_batch_sql1 = "UPDATE `{$databaseName1}`.`{$tableName1}` SET {$updateSqlStr1} WHERE ID IN({$whereIds1})";
                Db::connection('bbc_commodity')->update($sql_batch_sql1);

                if ($specPriceData) {
                    //执行批量更新  ly_goods_spec_price 规格价格表
                    $fields2        = ['sid', 'goods_id', 'spec_num', 'price_market', 'price_recommend', 'price_recommend_vip', 'price_cost', 'price_store', 'price_market_update'];
                    $sqlArr2        = $this->mergeSql($specPriceData, $fields2);
                    $updateSqlStr2  = implode(",", $sqlArr2['updateSql']);
                    $whereIds2      = implode(",", $sqlArr2['ids']);
                    $databaseName2  = GoodsSpecPrice::instance()->getConnection()->getDatabaseName();
                    $tableName2     = GoodsSpecPrice::instance()->getTable();
                    $sql_batch_sql2 = "UPDATE `{$databaseName2}`.`{$tableName2}` SET {$updateSqlStr2} WHERE ID IN({$whereIds2})";
                    Db::connection('bbc_commodity')->update($sql_batch_sql2);
                }
                if ($dstbPriceDel) {
                    //删除ly_distributor_price
                    DistributorPrice::whereIn('goods_id', $dstbPriceDel)->where('sid', getSID())->where('cid', $cid)->delete();
                }
                //MnStoreGoods批量更新
                if ($storeGoodsData) {
                    $newStoreGoodsData = array_column($storeGoodsData, null, 'id');
                    $chunkData1        = array_chunk($newStoreGoodsData, self::CHUNK_NUM);
                    foreach ($chunkData1 as $k11 => $upData11) {
                        //执行批量更新  ly_mn_store_goods 表
                        $fields3        = ['type', 'profit', 'profit_vip', 'price', 'price_vip', 'goods_id', 'md', 'is_high_goods'];
                        $sqlArr3        = $this->mergeSql($upData11, $fields3);
                        $updateSqlStr3  = implode(",", $sqlArr3['updateSql']);
                        $whereIds3      = implode(",", $sqlArr3['ids']);
                        $databaseName3  = MnStoreGoods::instance()->getConnection()->getDatabaseName();
                        $tableName3     = MnStoreGoods::instance()->getTable();
                        $sql_batch_sql3 = "UPDATE `{$databaseName3}`.`{$tableName3}` SET {$updateSqlStr3} WHERE ID IN({$whereIds3})";
                        Db::connection('bbc_commodity')->update($sql_batch_sql3);
                    }
                }
                //ly_cash_goods_change 新增
                if ($cashGoodsChangeData) {
                    CashGoodsChange::insert($cashGoodsChangeData);
                }
                //新增分销商等级价格  ly_distributor_price
                if ($dstbPriceData) {
                    DistributorPrice::insert($dstbPriceData);
                }
                if ($goodsLogData) {
                    GoodsLog::insert($goodsLogData);
                }
                //计算进度条
                $per        = bcdiv((string)($k + 1), (string)$count, 4);
                $currentPer = bcmul(bcmul($per, '100', 2), '0.88', 2);
                $pushPer    = bcadd($currentPer, (string)$percent, 2);
                if ($server) {
                    $send = Normal::returnCode(Normal::WS_START, "进行中", [
                        'percent' => $pushPer,
                    ]);
                    $server->push($fd, json_encode($send, JSON_UNESCAPED_UNICODE));
                }
            }
            Db::commit();
        } catch (\Throwable $th) {
            Db::rollBack();
            return Normal::returnCode(Normal::WS_ERROR, "批量更新数据失败：" . $th->getMessage());
        }
        //保存到导入日志
        $importLog = [
            'cid'             => $cid,
            'file_name'       => $originFileName,
            'import_type'     => 2,
            'all_num'         => count($list),
            'success_num'     => $count,
            'fail_num'        => count($errorData),
            'status'          => count($errorData) > 0 ? 2 : 1,
            'origin_file_url' => $originFileUrl,
            'fail_file_url'   => $download_url ?? '',
            'manager_id'      => $manager_id,
            'manager_name'    => $managerInfo['name'],
            'cd'              => $timeStp,
            'md'              => $timeStp,
        ];
        GoodsImportLog::insert($importLog);
        return Normal::returnCode(Normal::WS_END, "已完成", [
            'percent'      => 100.00,
            'download_url' => $download_url ?? '',
        ]);
    }

    /**
     * 组装批量更新的SQL 语句
     * @param array $upData
     * @param array $fields
     * @return array
     * @author huj
     * @DateTime 2022-04-01 09:54:44
     */
    public function mergeSql($upData, $fields) {
        //需要更新的字段
        $updateSqlColumns = $fields;
        $when             = [];
        foreach ($upData as $v1) {
            foreach ($updateSqlColumns as $column) {
                $then            = $v1[$column];
                $when[$column][] = "WHEN {$v1['id']} THEN '{$then}'";
            }
        }
        $updateSql = [];
        foreach ($updateSqlColumns as $column) {
            $updateSql[] = "{$column} = CASE id " . (implode(" ", $when[$column])) . " END";
        }
        return [
            'ids'       => array_column($upData, 'id'),
            'updateSql' => $updateSql,
        ];
    }

    //excel头部
    public function getColumns($distributorLevel) {
        $excelTitle = ['sku', '规格数量', '下游结算价', '推荐会员价', '推荐零售价', '市场价(非必填)', '成本价', '名称', '国际编码'];
        foreach ($distributorLevel as $v) {
            $excelTitle[] = $v;
        }
        array_push($excelTitle, '错误信息');
        return $excelTitle;
    }

    /**
     * 获取后台操作人员信息
     */
    public function managerInfo($manager_id) {
        return ManagerChannel::instance()->info(['id' => $manager_id]);
    }

    /**
     * 使用正则验证数据
     * @access public
     * @param mixed $value 字段值
     * @param mixed $rule 验证规则 正则规则或者预定义正则名
     * @return bool
     */
    protected function regex($value, $rule) {
        return is_scalar($value) && 1 === preg_match($rule, (string)$value);
    }

}